<template>
  <div class="interface-wrap">

    <div v-if="!isFull" class="api-title">接口参数配置
      <el-button class="full-btn" size="mini" icon="el-icon-rank" @click="isFull = !isFull">全屏</el-button>
    </div>

    <div class="full-div" :class="{active: isFull}">
      <div v-if="isFull" class="api-title">接口参数配置
        <el-button class="full-btn" size="mini" icon="el-icon-rank" @click="isFull = !isFull">退出全屏</el-button>
      </div>

      <div v-if="interfaceDataTable.length > 0" style="margin-bottom: 10px">
        <div v-if="isTableRow">
          <el-table v-loading="loading" :data="interfaceDataTable">
            <el-table-column prop="name" label="请求参数" width="180"></el-table-column>
            <el-table-column prop="type" label="参数类型" width="180"></el-table-column>
            <el-table-column prop="httpType" label="请求类型"></el-table-column>
            <el-table-column prop="desc" label="描述"></el-table-column>
            <el-table-column label="值">
              <template slot-scope="scope" >
                <el-input :data-node-id="scope.row.nodeId" :disabled="disabled" size="mini" type="text" v-model="scope.row.dataValue" style="width:120px;"></el-input>
                <i class="el-icon-circle-plus add-btn" v-if="parentInterfaceList.length > 0 && !disabled" @click="onclickUpInterface(scope.row, scope.$index, 'headerOrQuery')"></i>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <div v-if="Object.keys(descList).length > 0">
        <el-row :gutter="15" class="wrap-json">
          <el-col :span="12" class="wrap-json">
            <div class="json-bg" style="padding-bottom: 15px;">
              <show-json-desc :json-object="descList" />
            </div>
          </el-col>
          <el-col :span="12" class="wrap-json">
            <div class="json-bg" style="padding-bottom: 8px;">
              <el-form ref="form" label-width="160px">
                <ul id="jsonList">
                  <li class="json-item" v-for="(item,index) in fileDataList" :key="index">
                    <div class="json-key" v-html="item.str"></div>
                    <input class="input" :data-node-id="item.nodeId" v-if="item.isInput" v-model="item.dataValue" :disabled="disabled" :placeholder="item.placeholder"/>
                    <!--<el-input :data-node-id="item.nodeId" v-model="item.dataValue" size="mini" :disabled="disabled" v-if="item.isInput" :placeholder="item.placeholder"></el-input>-->
                    <i class="el-icon-circle-plus add-btn"
                       v-if="item.isInput && parentInterfaceList.length > 0 && !disabled"
                       @click="onclickUpInterface(item, index, 'body')">
                    </i>
                  </li>
                </ul>
              </el-form>
            </div>
          </el-col>
        </el-row>
      </div>
    </div>

    <div v-if="!isFullAssert" class="api-title">断言判断
      <el-button class="full-btn" size="mini" icon="el-icon-rank" @click="isFullAssert = !isFullAssert">全屏</el-button>
    </div>
    <div class="full-div" :class="{active: isFullAssert}">
      <div v-if="isFullAssert" class="api-title">断言判断
        <el-button class="full-btn" size="mini" icon="el-icon-rank" @click="isFullAssert = !isFullAssert">退出全屏</el-button>
      </div>

      <div class="not-data" v-if="Object.keys(assertDesc).length === 0">暂无断言数据</div>
      <el-row :gutter="15" class="wrap-json" v-else>
        <el-col :span="12" class="wrap-json">
          <div class="json-bg" :id="assertId">
            <show-json-desc :json-object="assertDesc" />
          </div>
        </el-col>
        <el-col :span="12" class="wrap-json">
          <div class="json-bg">
            <div class="assert">
              <div class="not-data" v-if="assert.length === 0">点击左侧添加断言条件</div>
              <div class="assert-row" v-for="(item,index) in assert" style="margin-bottom: 10px;">
                <div class="assert-row-left">
                  <el-row :gutter="15">
                    <el-col :span="5">
                      <span v-if="index === 0">&nbsp;</span>
                      <el-select v-if="index > 0" v-model="item.groupCondition" style="width: 100%" size="mini" :disabled="disabled">
                        <el-option v-for="(item,index) in conditionList" :key="index" :label="item.value" :value="item.key"></el-option>
                      </el-select>
                    </el-col>
                    <el-col :span="5">
                      <el-input v-model="item.key" placeholder="请输入字段名称" disabled size="mini"></el-input>
                    </el-col>
                    <el-col :span="7">
                      <el-select v-model="item.condition" style="width: 100%" size="mini" :disabled="disabled">
                        <el-option v-for="(child,index) in item.typeList" :key="index" :label="child.desc" :value="child.index + ''"></el-option>
                      </el-select>
                    </el-col>
                    <el-col :span="7">
                      <el-input v-model="item.value" placeholder="请输入字段值" size="mini" :disabled="disabled"></el-input>
                    </el-col>
                  </el-row>
                </div>
                <div class="assert-row-right">
                  <i v-if="!disabled" class="el-icon-remove" @click="deleteAssert(index)"></i>
                </div>
              </div>
            </div>
          </div>
        </el-col>
      </el-row>
    </div>

    <transition name="fade">
      <select-out-value v-if="jsonDialog" @selectOutValueCall="selectOutValueCall"/>
    </transition>

  </div>
</template>

<script>
  import ShowJsonDesc from '../../compoents/ShowJsonDesc'
  import { jsonMain, jsonBody, toContainJavaType, toDataType } from "@/libs/utils";
  import SelectOutValue from "./SelectOutValue"
  let CircularJSON = require('circular-json'); //导入可转正在循环引用的对象
  export default {
    components: {
      ShowJsonDesc, SelectOutValue
    },
    name: "InterfaceConfig",
    props: {
      //当前接口对象
      node: {
        type: Object,
        required: true
      },
      //是否禁用输入框
      disabled: {
        type: Boolean,
        default: false
      },
      //判断是修改还是新增
      dataType: Number,
      //断言的ID
      assertId: {
        type: String,
        default: "assertResultJson"
      }
    },
    data () {
      return {
        loading: false,
        nodeData: null,               //接口对象
        descList: {},                 //用于存放描述json
        selectInterface: "",          //选择的接口对象
        parentInterfaceList: this.$store.getters.parentInterfaceList,      //存父接口接口对象
        interfaceDataTable: [],       //参数列表
        interfaceData: {},            //接口数据
        fileDataList: [],             //显示json格式数据
        jsonDialog: false,            //是否显示出参弹窗
        isTableRow: true,             //刷新table,
        assert: [],
        isFull: false,                //是否全屏
        isFullAssert: false,          //是否全屏断言
        groupList: [],                //比较运算符
        conditionList: [],            //关系运算符
        assertDesc: {},
      }
    },
    created() {
      this.getGroup();
      this.getConditions();
      this.initData();
    },
    methods: {
      /**获取比较运算符**/
      getGroup() {
        this.$http.get("/assert/compare/conditions/group").then(res => {
          this.groupList = res;
        });
      },
      /**获取关系运算符**/
      getConditions() {
        this.$http.get("/assert/link/conditions").then(res => {
          this.conditionList = res;
        });
      },
      /**初始化数据**/
      initData() {
        this.nodeData = this.node;
        console.log("interfaceConfig的node对象:", this.nodeData);

        console.log("this.nodeData.siaRequestData: ", this.nodeData.siaRequestData);

        //1.转JSON对象
        this.nodeData = JSON.parse(CircularJSON.stringify(this.nodeData));
        this.nodeData.siaRequestData = JSON.parse(this.nodeData.siaRequestData);
        this.nodeData.siaRequestDataJson = JSON.parse(this.nodeData.siaRequestDataJson);

        //转出参
        let detail = JSON.parse(this.nodeData.siaResponseData).detail;
        detail.forEach(item => {
          let assertJson = jsonBody(item);
          for (let key in assertJson) {
            this.assertDesc[key] = assertJson[key];
          }
        })

        let siaRequestDataJson = {}; //用于最终显示在页面的json对象
        //2.筛选数据
        this.nodeData.siaRequestData.forEach(item => {
          //判断数据类型
          switch (item.httpType) {
            case "header":
              this.interfaceDataTable.push(item);
              break;
            case "query":
              this.interfaceDataTable.push(item);
              break;
            case "body":
              //判断是否还有下级节点--没有下级节点
              if (item.leaf && !item.detail) {
                let json = jsonBody(item);
                for (let key in json) {
                  this.descList[key] = json[key];
                }
                //判断是否是回显更新
                if (this.nodeData.updateInterfaceJson != undefined) {
                  siaRequestDataJson = this.nodeData.updateInterfaceJson;
                }
                else {
                  siaRequestDataJson = this.nodeData.siaRequestDataJson;
                }
              }
              //有下级节点
              else {
                this.descList = jsonMain(item);
                //判断是否是回显更新
                if (this.nodeData.updateInterfaceJson != undefined) {
                  siaRequestDataJson = this.nodeData.updateInterfaceJson;
                }
                else {
                  siaRequestDataJson[item.name] = this.nodeData.siaRequestDataJson[item.name];
                }
              }
              break;
          }
        });

        //3.判断inQuery、inHeader是否是回显更新，是则填充
        if(this.nodeData.updateParamsJson != undefined) {
          this.interfaceDataTable.forEach((item, index) => {
            for (let key in this.nodeData.updateParamsJson.inQuery) {
              if (item.name == key) {
                this.interfaceDataTable[index].dataValue = this.nodeData.updateParamsJson.inQuery[key];
              }
            }
            for (let key in this.nodeData.updateParamsJson.inHeader) {
              if (item.name == key) {
                this.interfaceDataTable[index].dataValue = this.nodeData.updateParamsJson.inHeader[key];
              }
            }
          })
        }

        if (siaRequestDataJson) { //判断是否有inBody
          //4.调用生成json带输入框的格式
          this.fileDataList = this.changeData(this.convert([], siaRequestDataJson, 0, ""));
          //5.填充值
          this.resetData(siaRequestDataJson);
        }

        //6.绑定断言点击事件
        setTimeout(() => {
          let _this = this;
          $(function () {
            $("#" + _this.assertId).find(".key").on("click", function () {
              //调用添加断言条件
              _this.addAssert($(this).find("input[type=hidden]").val(), $(this).find("input[type=hidden]").attr("dataType"));
            })
          })

          //7.判断还原断言条件
          this.assert = this.nodeData.updateAssertJson ? this.nodeData.updateAssertJson : [];
          this.assert.forEach(item => {
            item.typeList = this.groupList[toDataType(item.type)];
          });
        }, 100);

      },
      /**填充输入框里面值**/
      resetData(obj) {
        for (let a in obj) {
          if (obj[a] instanceof Object) {
            this.resetData(obj[a]);
          } else {
            for (let b = 0; b < this.fileDataList.length; b++) {
              let changeStr = this.fileDataList[b].str.replace(/&nbsp;/g, '')
              changeStr = changeStr.substr(0, changeStr.length - 1)
              if (a == changeStr) {
                if (toContainJavaType(obj[a])) {
                  this.fileDataList[b].placeholder = obj[a];
                  this.fileDataList[b].dataValue = "";
                }
                else {
                  this.fileDataList[b].dataValue = obj[a]
                }
              }
            }
          }
        }
      },
      /**组装数组**/
      changeData(arrays) {
        let str, arr = [];
        for (let i = 0; i < arrays.length; i++) {
          str = arrays[i].replace(/&nbsp;/g, '')
          let s = str.substr(str.length - 1, 1)
          let item = {}
          if (s == ':') {
            item.str = arrays[i]
            item.file = arrays[i]
            item.isInput = true
          } else {
            item.str = arrays[i]
            item.file = ''
            item.isInput = false
          }
          arr.push(item)
        }
        return arr
      },
      /**递归生成json格式**/
      convert(arrays,obj,level,start) {
        let mark = "&nbsp;:&nbsp;";
        if (obj instanceof Array) {
          if (obj == null || obj == undefined || obj.length == 0) {
            arrays.push(start + "[" + "]");
          } else {
            arrays.push(start + "[");
            for (let index in obj) {
              let value = obj[index];
              let temp = this.countSpace(level + 1);
              if (value instanceof Object || value instanceof Array) {
                this.convert(arrays, value, level + 1, temp);
              } else {
                arrays.push(temp + value);
              }
            }
            arrays.push(this.countSpace(level) + "]");
          }
        } else if (obj instanceof Object) {
          arrays.push(start + "{");
          for (let key in obj) {
            let value = obj[key];
            // console.log(obj,value);
            let temp = this.countSpace(level + 1) + key + mark;
            if (value instanceof Object || value instanceof Array) {
              this.convert(arrays, value, level + 1, temp);
            }
            else {
              arrays.push(temp);
            }
          }
          arrays.push(this.countSpace(level) + "}");
        } else {
          arrays.push(obj);
        }
        return arrays
      },
      /**拼接空格**/
      countSpace(index){
        let str ="";
        let temp = "&nbsp;&nbsp;&nbsp;&nbsp;"
        for(let i=0;i<index;i++){
          str += temp
        }
        return str;
      },
      /**点击选择出参**/
      onclickUpInterface(item,index,type) {
        this.inType = type; // 点击添加的类型
        this.currentIndex = index; // 点击加号的下标
        this.currentNode = item; //当前接口参数的 当前点击添加的KEY
        this.jsonDialog = true
      },
      /**选择json的回调**/
      selectOutValueCall(val, nodeId) {
        if (val) {
          if(this.inType === "headerOrQuery") {
            this.interfaceDataTable[this.currentIndex].dataValue = nodeId ? nodeId + "." + val : val;
            this.interfaceDataTable[this.currentIndex].nodeId = nodeId;
          }
          else {
            this.fileDataList[this.currentIndex].dataValue = nodeId ? nodeId + "." + val : val;
            this.fileDataList[this.currentIndex].nodeId = nodeId;
          }
        }
        this.isTableRow = false;
        this.$nextTick(() => {
          this.isTableRow = true;
        })
        this.jsonDialog = false;
      },
      /**字符串转json**/
      stringToJson(json_string) {
        let json = {}
        if (json_string != '') {
          json_string = json_string.replace(/ /g, "");
          json_string = json_string.replace(/,}/g, "}");
          json_string = json_string.replace(/},]/g, "}]");
          json_string = json_string.replace(/},}/g, "}]");
          json_string = json_string.replace(/(?:\s*['"]*)?([a-zA-Z0-9]+)(?:['"]*\s*)?:/g, "'$1':");
          json = eval('(' + json_string + ')');
        }
        return json;
      },
      /**添加断言条件**/
      addAssert(key, type) {
        if (this.disabled) {
          return;
        }
        this.assert.push({
          key: typeof key === "string" ? key : "",
          groupCondition: "AND",
          condition: "9",
          value: "",
          type: toDataType(type),
          typeList: this.groupList[toDataType(type)]
        })
      },
      /**删除断言条件**/
      deleteAssert(index) {
        this.assert.splice(index, 1);
      },
      /**获取参数json（提供方法）**/
      getParamsJson() {
        let inQuery = {},inHeader = {};
        this.interfaceDataTable.forEach(item => {
          if (item.httpType == "header") {
            inHeader[item.name] = item.dataValue;
          }
          else if (item.httpType == "query") {
            inQuery[item.name] = item.dataValue;
          }
        });
        return {inQuery, inHeader};
      },
      /**获取接口数据json（提供方法）**/
      getInterfaceJson() {
        let json = "";
        $("#jsonList li").each(function(index, el) {
          let text = $(el).text().replace(/(^\s*)|(\s*$)/g, "");
          let val = $(el).find("input").val();
          let nodeId = $(el).find("input").attr("data-node-id");
          console.log("nodeId: ", nodeId);
          if (text === "}") {
            json += text + ","
          }
          else if (text === "]") {
            json += text + ","
          }
          else {
            json += text;
          }
          if (val !== undefined) {
            if (nodeId) {
              //val = nodeId + "." + val;
            }
            json += val === "" ? "\"\"" + "," : "\"" + val + "\",";
          }
        });
        return this.stringToJson(json.substring(0, json.length - 1));
      },
      /**获取断言条件（提供方法）**/
      getAssert() {
        let tempAssert = this.assert;
        tempAssert = JSON.parse(JSON.stringify(tempAssert));
        tempAssert.forEach(item => {
          delete item.typeList;
        })
        return tempAssert;
      },
    }
  }
</script>
<style>
  .interface-wrap #jsonList .el-input.el-input--mini{
    display: inline;
  }
  .interface-wrap #jsonList input[type=text]{
    height: 26px;
    line-height: 26px;
    width: 160px;
  }
  .interface-wrap .el-table__header thead th{
    background: #fff;
    color: #666;
  }
</style>
<style scoped lang="less">
  .api-title{font-size: 18px;color: #409eff; margin:15px 0;font-weight: bolder;position: relative;}
  .api_info span{color:#333;}
  .add-btn{cursor:pointer;margin-left:10px;color: #409EFF;font-size: 20px;position: relative;top: 2px;}
  .wrap-json{height: 100%}
  .json-bg {
    position: relative;
    background: #f4f4f5;
    min-width: 100%;
    max-width: 100%;
    min-height: 100%;
    border-radius: 6px;
  }
  .json-bg ul{padding: 0 5px;}
  .json-bg .json-item{height: 30px;line-height: 30px;}
  .json-bg .json-item .json-key{display: inline-block;font-size: 12px;width: 160px;}
  .input{
    height: 26px;
    line-height: 26px;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    color: #606266;
    outline: none;
    padding: 0 15px;
    font-size: 12px;
  }
  .full-div{
    width: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 200px;
    max-height: 400px;
    resize: vertical;
    position: relative;
    transition: background 0.3s;
    background: rgba(0, 0, 0, 0);
    &.active{
      position: fixed;
      z-index: 9999;
      height: 100% !important;
      max-height: 100% !important;
      background: rgba(255, 255, 255, 1);
      top: 0;
      left: 0;
      padding: 0 15px 15px 15px;
      box-sizing: border-box;
      animation: zoom 300ms alternate;
      resize: none;
    }
  }
  .full-btn{
    position: absolute;
    top: 0;
    right: 5px;
    z-index: 1;
  }

  @keyframes zoom {
    to{
      transform: scale(1);
    }
    from{
      transform: scale(0.8);
    }
  }

  .assert{
    padding: 15px;
    .assert-row{
      display: flex;
      &-left{
        width: calc(100% - 40px);
      }
      &-right{
        width: 40px;
        text-align: center;
        i{
          font-size: 20px;
          color: #f56c6c;
          position: relative;
          top: 3px;
          cursor: pointer;
        }
      }
    }
  }
  .not-data{
    padding: 30px;
    text-align: center;
    color: #999999;
  }
</style>
